package com.example.xd.tuiliu_test.videoplayer.widget;



import android.app.Activity;
import android.content.Context;
import android.graphics.Color;
import android.graphics.SurfaceTexture;
import android.media.AudioManager;
import android.provider.Settings;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.Surface;
import android.view.ViewGroup;
import android.widget.FrameLayout;

import androidx.fragment.app.Fragment;

import com.example.xd.tuiliu_test.videoplayer.PlayerManager;
import com.example.xd.tuiliu_test.videoplayer.exception.ActivityIsNullException;
import com.example.xd.tuiliu_test.videoplayer.exception.MethodNotImplemented;
import com.example.xd.tuiliu_test.videoplayer.lifecyclemanager.ILifecycle;
import com.example.xd.tuiliu_test.videoplayer.lifecyclemanager.LifecycleManager;
import com.example.xd.tuiliu_test.videoplayer.model.VideoModel;
import com.example.xd.tuiliu_test.videoplayer.render.ResizeTextureView;
import com.example.xd.tuiliu_test.videoplayer.render.listener.ISurfaceListener;
import com.example.xd.tuiliu_test.videoplayer.util.ScanForActivity;
import com.example.xd.tuiliu_test.videoplayer.widget.status.BackPauseStatus;
import com.example.xd.tuiliu_test.videoplayer.widget.status.BaseStatus;
import com.example.xd.tuiliu_test.videoplayer.widget.status.CompleteListener;
import com.example.xd.tuiliu_test.videoplayer.widget.status.ErrorStatus;
import com.example.xd.tuiliu_test.videoplayer.widget.status.InitingStatus;
import com.example.xd.tuiliu_test.videoplayer.widget.status.PauseStatus;
import com.example.xd.tuiliu_test.videoplayer.widget.status.PlayingStatus;
import com.example.xd.tuiliu_test.videoplayer.widget.status.WaitInitStatus;
import com.example.xd.tuiliu_test.videoplayer.widget.status.WaitNetStatus;
import com.example.xd.tuiliu_test.videoplayer.widget.status.WaitWifiStatus;

import java.io.IOException;
import java.util.List;

import tv.danmaku.ijk.media.player.IMediaPlayer;


/**
 * 播放器顶级父类
 * 播放器结构
 * BasePlayerView 提供最基础的渲染播放功能，无UI                           播放内核层
 * ↓
 * ControllerView 提供控制播放的UI                                         基础UI层
 * ↓
 * InitByOtherPlayerView 提供了接管另外一个播放器播放状态的功能            基础功能层
 * ↓
 * GeneralPlayerView 普通播放器 具有全屏功能                               播放器应用层
 * ListItemPlayerView 列表播放器 禁止了音量亮度控制和全屏功能              播放器应用层
 * NoControllerPlayerView 没有控制ui的播放器                               播放器应用层
 */
abstract public class BasePlayerView extends FrameLayout implements ILifecycle, ISurfaceListener, IMediaPlayer.OnPreparedListener, IMediaPlayer.OnCompletionListener, IMediaPlayer.OnBufferingUpdateListener, IMediaPlayer.OnSeekCompleteListener, IMediaPlayer.OnErrorListener, IMediaPlayer.OnInfoListener, IMediaPlayer.OnVideoSizeChangedListener {
    Context mContext;
    //播放器内核
    public IMediaPlayer player;
    Activity activity;
    //不同清晰度的播放源list
    List<VideoModel> videoModels;
    //单一清晰度的播放源
    VideoModel videoModel;
    //视频时长
    protected long duration = 0;
    //播放时长
    public long playTime = 0;
    //是否已经释放 默认为true 初始化之后为false
    public boolean release = true;
    //绘制视频的TextureView
    public ResizeTextureView textureView;
    //绘制视频的TextureView
    public SurfaceTexture surfaceTexture;
    //播放器的状态
    public BaseStatus status = null;
    //播放器的状态 --错误
    public BaseStatus error = new ErrorStatus(this);
    //播放器的状态 --从暂停退到后台
    public BaseStatus backPause = new BackPauseStatus(this);
    //播放器的状态 --正在初始化
    public BaseStatus initing = new InitingStatus(this);
    //播放器的状态 --正在播放
    public BaseStatus playing = new PlayingStatus(this);
    //播放器的状态 --正在暂停
    public BaseStatus pause = new PauseStatus(this);
    //播放器的状态 --等待初始化
    public BaseStatus waitinit = new WaitInitStatus(this);
    //播放器的状态 --等待网络
    public BaseStatus waitnet = new WaitNetStatus(this);
    //播放器的状态 --等待wlan网络
    public BaseStatus waitwifi = new WaitWifiStatus(this);
    //循环播放 循环播放的功能暂时由播放器实现 而不是使用ijk内核实现的
    public boolean isLooper = true;
    //有了子view之后 生命周期应该由子view接管
    public boolean hasChild = false;
    Fragment fragment;
    CompleteListener completeListener;

    public BasePlayerView(Context context) {
        this(context,null);
    }

    public BasePlayerView(Context context, AttributeSet attrs) {
        this(context, attrs,0);
    }

    public BasePlayerView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        this.mContext = context;
        initView();
    }

    /**
     * 初始化播放器 创建播放器就会调用 完成了生命周期的绑定
     *
     * @作者 fengao
     * @创建日期 2019/3/5 14:47
     */
    protected void initView() {
        setBackgroundColor(Color.parseColor("#000000"));
        Activity activity = ScanForActivity.scanForActivity(mContext);
        if (activity == null) {
            throw new ActivityIsNullException();
        }
        this.activity = activity;
        LifecycleManager.getInstance().registerPlayer(this);
    }

    public VideoModel getVideoModel() {
        return videoModel;
    }

    /**
     * 播放视频时才会调用 释放后 再次播放也需要调用 设置了播放view 完成了渲染层的初始化
     *
     * @作者 fengao
     * @创建日期 2019/3/5 14:53
     */
    public void initVideo() {
        release = false;
        if (PlayerManager.getInstance().getPlayingView() != null) {
            PlayerManager.getInstance().getPlayingView().releasePlayer();
        }
        initTextureView();
    }

    /**
     * 初始化渲染层 初始化音量和亮度
     *
     * @作者 fengao
     * @创建日期 2019/3/5 14:55
     */
    void initTextureView() {
        textureView = new ResizeTextureView(mContext);
        LayoutParams layoutParams =
                new LayoutParams(
                        ViewGroup.LayoutParams.MATCH_PARENT,
                        ViewGroup.LayoutParams.MATCH_PARENT,
                        Gravity.CENTER);
        addView(textureView, 0, layoutParams);
        if (player == null) {
            player = PlayerManager.getInstance().createIjkPlayer();
            initVolumeAndLuminance();
        }
        textureView.setISurfaceListener(this);
    }

    protected void initVolumeAndLuminance() {
        AudioManager am = (AudioManager) getContext().getSystemService(Context.AUDIO_SERVICE);
        assert am != null;
        float current = am.getStreamVolume(AudioManager.STREAM_SYSTEM);
        int max = am.getStreamMaxVolume(AudioManager.STREAM_SYSTEM);
        initVolume((int) (current * 100) / max);
        int systemBrightness = getSystemBrightness();
        initLuminance(systemBrightness * 100 / 255);
    }

    //初始化音量及亮度的UI 放在了UI层处理
    protected abstract void initVolume(int volume);

    protected abstract void initLuminance(int luminance);

    private int getSystemBrightness() {
        int systemBrightness = 0;
        try {
            systemBrightness = Settings.System.getInt(getContext().getContentResolver(), Settings.System.SCREEN_BRIGHTNESS);
        } catch (Settings.SettingNotFoundException e) {
            e.printStackTrace();
        }
        return systemBrightness;
    }


    public void setLooper(boolean looper) {
        this.isLooper = looper;
        player.setLooping(looper);
    }

    //释放掉一切相关资源 恢复到等待初始化的状态
    //TODO 保存进度和src
    public void releasePlayer() {
        if (status != null) {
            status.releasePlayer();
        }
    }

    public void setCompleteListener(CompleteListener completeListener) {
        this.completeListener = completeListener;
    }

    public boolean isPlaying() {
        if (player == null) {
            return false;
        } else {
            return player.isPlaying();
        }
    }

    public void play() {
        status.play();
    }

    public void pause() {
        status.pause();
    }

    public void setVideoModel(VideoModel videoModel) {
        this.videoModel = videoModel;
        ((ControllerView) this).playTime = 0;
        setStatus(waitinit);
        if (videoModel.autoPlayWithLastPlayer) {
            if (autoStartWithLastPlayer()) {
                return;
            }
        }
        if (videoModel.autoPlay) {
            status.play();
            return;
        }

    }

    /**
     * 自动从上一个view复播 用于列表和详情切换,使用之前必须先设置播放源否则无效
     */
    private boolean autoStartWithLastPlayer() {
        InitByOtherPlayerView playerView = (InitByOtherPlayerView) PlayerManager.getInstance().getPlayingView();
        if (playerView != null && playerView.videoModel != null && this.videoModel != null && !this.videoModel.src.equals("") && playerView.videoModel.src.equals(videoModel.src)) {
            playerView.parentReleaseTextureView();
            ((InitByOtherPlayerView) this).parentPlayer = playerView;
            ((InitByOtherPlayerView) this).startWithParent(playerView);
            return true;
        }
        return false;
    }

    /**
     * 设置状态机 并且完成了状态机生命周期的条用
     *
     * @作者 fengao
     * @创建日期 2019/3/5 15:24
     */
    public void setStatus(BaseStatus status) {
        if (this.status != null) {
            this.status.onStopStatus();
        }
        this.status = status;
        if (this.status != null) {
            this.status.onStartStatus();
        }
    }

    //TODO 多清晰度模式

    /**
     * 多码率模式使用，暂时未完成
     *
     * @param videoModels
     */
    public void setVideoModels(List<VideoModel> videoModels) {
        this.videoModels = videoModels;
        initDefinitionView();
    }

    protected abstract void initDefinitionView();

    void prepare() {
        try {
            player.setDataSource(videoModel.src);
            player.prepareAsync();
            player.setOnPreparedListener(this);
            player.setAudioStreamType(AudioManager.STREAM_MUSIC);
            player.setOnCompletionListener(this);
            player.setOnBufferingUpdateListener(this);
            player.setScreenOnWhilePlaying(true);
            player.setOnSeekCompleteListener(this);
            player.setOnErrorListener(this);
            player.setOnInfoListener(this);
            player.setOnVideoSizeChangedListener(this);
            player.setLooping(isLooper);
            if (surfaceTexture != null) {
                player.setSurface(new Surface(surfaceTexture));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void fullScreen() {
        throw new MethodNotImplemented();
    }

    public void exitFullScreen() {
        throw new MethodNotImplemented();
    }

    //通知播放器开始滑动
    public void onStartScrolled() {
        if (status != null) {
            status.onStartScrolled();
        }
    }

    //通知播放器结束滑动
    public void onEndScrolled() {
        if (status != null) {
            status.onEndScrolled();
        }
    }

    @Override
    public Activity getActivityForLifecycle() {
        return activity;
    }

    @Override
    public Fragment getFragmentForLifecycle() {
        return fragment;
    }

    BasePlayerView getCloneView() {
        return this;
    }

    void switchDefinition(VideoModel videoModel) {
        //TODO 切换码率
    }

    @Override
    public void onSurfaceAvailable(SurfaceTexture surface, int width, int height) {
        if (this.surfaceTexture == null) {
            this.surfaceTexture = surface;
            prepare();
        } else {
            this.textureView.setSurfaceTexture(this.surfaceTexture);
        }
    }

    @Override
    public void onSurfaceSizeChanged(SurfaceTexture surface, int width, int height) {

    }

    @Override
    public boolean onSurfaceDestroyed(SurfaceTexture surface) {
        return false;
    }

    @Override
    public void onSurfaceUpdated(SurfaceTexture surface) {

    }

    @Override
    public void onPrepared(IMediaPlayer iMediaPlayer) {
        status.onPrepared(iMediaPlayer);
    }

    @Override
    public void onCompletion(IMediaPlayer iMediaPlayer) {
        status.completed();
        ((ControllerView) this).playTime = 0;
        if (completeListener != null) {
            completeListener.complete();
        }
    }

    @Override
    public void onBufferingUpdate(IMediaPlayer iMediaPlayer, int i) {

    }

    @Override
    public void onSeekComplete(IMediaPlayer iMediaPlayer) {

    }

    @Override
    public boolean onError(IMediaPlayer iMediaPlayer, int i, int i1) {
        status.error();
        return false;
    }

    @Override
    public boolean onInfo(IMediaPlayer iMediaPlayer, int what, int i1) {
        status.onInfo(iMediaPlayer, what, i1);
        return false;
    }

    abstract void showLoading();

    abstract void removeLoading();

    @Override
    public void onVideoSizeChanged(IMediaPlayer iMediaPlayer, int i, int i1, int i2, int i3) {
        //刷新播放器播放比例
        textureView.setVideoSize(i, i1);
    }

    @Override
    public void onCreate() {

    }

    @Override
    public void onStop() {
        if (hasChild) {
            return;
        }
        status.onBack();
    }

    @Override
    public void onStart() {
        status.onStart();
    }

    @Override
    public void onDestroy() {
        if (hasChild) {
            return;
        }
        if (!release) {
            releasePlayer();
        }
    }

    abstract public void onProgressUpdate(final long position, final long duration);

    abstract public void startProgressTimer();

    abstract public void cancelProgressTimer();
}
